package com.module.base.base.adapter;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SimpleItemAnimator;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

import com.module.base.base.adapter.proxy.RefreshLayoutProxy;
import com.module.base.bus.RecycledViewScrollStateBus;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Description :
 *
 * @author bsnl_yanxuwen
 * @date 2019/12/1615:08
 * 替换RefreshLayoutProxy 加载功能，使用Adapter实现加载
 * 使用OnRefreshPageListener来监听
 * 建议adapter.bindToRecyclerView(recyclerview); 替换 recyclerview.setAdapter(adapter);
 * <p>
 * 不能使用进行刷新,  因为getCurPosition没有包含了头部
 * getAdapter().notifyItemChanged(holder.getCurPosition());
 * 请使用
 * getAdapter().notifyItemChangedAndHead(holder.getCurPosition());
 * 或者
 * getAdapter().notifyItemChanged(holder.getRealPosition());
 */
public abstract class BaseNewAdapter<T> extends BaseDiscardAdapter<T, BaseNewViewHolder> {

    public int startPage = 0;//页数的初始值
    public int page_no = startPage; //当前页数
    public int page_size = 10;//加载数量
    private int realFirstPosition = -1;
    public Map<Integer, Boolean> map_animate;
    private boolean isRefresh;
    private boolean isFirstRefresh;
    private int refreshCount;
    public boolean onViewIdleFirstWindow = true;
    public boolean isScroll;//是否在滚动
    //是否使用adapter 的无数据,true 使用adapter无数据，false为刷新库的无数据
    private boolean isAdapterNoData;


    public interface OnRefreshPageListener {
        void onLoadPage(boolean isPull, boolean isRefresh);
    }

    public RecyclerListener mRecyclerListener;

    public void setRecyclerListener(@Nullable RecyclerListener listener) {
        this.mRecyclerListener = listener;
    }

    private Context context;

    private OnRefreshPageListener listener;

    private RefreshLayoutProxy refreshLayout;

    private final int MSG_FIRST_WINDOW = -9999;

    private Handler handler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what) {
                case MSG_FIRST_WINDOW:
                    onViewIdleFirstWindow((BaseNewViewHolder) msg.obj);
                    break;
            }
        }
    };

    public abstract BaseNewViewHolder onCreateNewViewHolder(ViewGroup parent, int viewType);

    public BaseNewAdapter() {
        super(null);
        map_animate = new HashMap<>();
    }

    @Override
    public int getItemViewType(int position) {
        return super.getItemViewType(position);
    }

    @Override
    public void bindToRecyclerView(RecyclerView recyclerView) {
        super.bindToRecyclerView(recyclerView);
        getRecyclerView().addOnScrollListener(new RecyclerView.OnScrollListener() {
            int lastFirstPosition = -1;
            int state;

            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                switch (newState) {
                    case RecyclerView.SCROLL_STATE_IDLE: //滚动停止
                        isScroll = false;
                        int firstPosition = getFirstVisibleItem();
                        if (lastFirstPosition != firstPosition && firstPosition >= 0 && getData().size() > firstPosition &&
                                getViewHolder(firstPosition) != null) {
                            onViewIdleFirstWindow(getViewHolder(firstPosition), false);
                        }
                        lastFirstPosition = firstPosition;
                        break;
                    case RecyclerView.SCROLL_STATE_DRAGGING: //手指拖动
                    case RecyclerView.SCROLL_STATE_SETTLING: //惯性滚动
                        isScroll = true;
                        break;
                }
                if (state != newState) {
                    RecycledViewScrollStateBus.Companion.send(newState);
                }
                this.state = newState;
            }


        });
    }

    @Override
    public final BaseNewViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return super.onCreateViewHolder(parent, viewType);
    }

    @Override
    protected final BaseNewViewHolder onCreateDefViewHolder(ViewGroup parent, int viewType) {
        if (parent.getContext() != null && context == null) {
            context = parent.getContext();
            if (context instanceof FragmentActivity && handler != null)
                ((FragmentActivity) context).getLifecycle().addObserver(new LifecycleObserver() {
                    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
                    public void onDestroy() {
                        destroy();
                    }

                });
        }
        BaseNewViewHolder holder = onCreateNewViewHolder(parent, viewType);
        holder.context = context;
        return holder;
    }

    /**
     * 重写，
     */
    @Override
    protected final BaseNewViewHolder createBaseViewHolder(ViewGroup parent, int layoutResId) {
        //禁止直接在adapter设置视图
//        return createBaseViewHolder(getItemView(layoutResId, parent));
        return createBaseViewHolder(parent);
    }

    @Override
    protected void convert(BaseNewViewHolder holder, T item) {
        if (!(holder instanceof EmptyHolder) && realFirstPosition < 0) {
            realFirstPosition = holder.getCurPosition();
        }
        holder.isViewRecycled = false;
        holder.setData(item);
        holder.convert(item, holder.getCurPosition());
    }

    /**
     * 替换原先的加载
     * 使用setRefreshPageListenner
     */
    @Override
    @Deprecated
    protected final void setOnLoadMoreListener(RequestLoadMoreListener requestLoadMoreListener, RecyclerView recyclerView) {
        super.setOnLoadMoreListener(requestLoadMoreListener, recyclerView);
    }

    /**
     * 替换原先的加载
     * 使用setRefreshPageListenner
     */
    @Override
    @Deprecated
    protected final void setOnLoadMoreListener(RequestLoadMoreListener requestLoadMoreListener) {
        super.setOnLoadMoreListener(requestLoadMoreListener);
    }

    /**
     * 设置刷新加载
     */
    public void setRefreshPageListenner(OnRefreshPageListener listener) {
        setRefreshPageListenner(refreshLayout, getRecyclerView(), listener);
    }

    /**
     * 设置刷新加载
     */
    public void setRefreshPageListenner(RefreshLayoutProxy refreshLayout, RecyclerView recyclerView, OnRefreshPageListener listener) {
        this.listener = listener;
        setRefreshLayout(refreshLayout);
        setOnLoadMoreListener(new RequestLoadMoreListener() {
            @Override
            public void onLoadMoreRequested() {
                if (refreshLayout != null) {
                    refreshLayout.setDisableLoadMore(true);
                }
                BaseNewAdapter.this.onLoadPage();
            }
        }, recyclerView);
        if (refreshLayout != null) {
            refreshLayout.setOnRefreshListener(new RefreshLayoutProxy.OnRefreshListener() {
                @Override
                public void onRefreshing() {
                    BaseNewAdapter.this.onRefreshing(true);
                }
            });
        }
    }

    public boolean isRefresh() {
        return isRefresh;
    }

    public boolean isFirstRefresh() {
        return isFirstRefresh;
    }

    public void setRefresh(boolean refresh) {
        isRefresh = refresh;
    }

    /**
     * 建议使用
     * loadMoreComplete(boolean isSuccessful)
     */
    @Override
    @Deprecated
    protected void loadMoreComplete() {
        loadMoreComplete(true);
    }

    public void loadMoreComplete(boolean isSuccessful) {
        if (getRecyclerView() != null) {
            getRecyclerView().stopScroll();
        }
        super.loadMoreComplete();
        if (refreshLayout != null) {
            refreshLayout.refreshComplete(isSuccessful);
        }
    }

    /**
     * 执行刷新
     */
    public void autoRefresh() {
        onRefreshing(false);
    }

    private void onRefreshing(boolean isPull) {
        setRefresh(true);
        if (listener != null) {
            resetPage();
            listener.onLoadPage(isPull, true);
        }
    }

    private void onLoadPage() {
        setRefresh(false);
        if (listener != null) {
            listener.onLoadPage(false, false);
        }
    }

    /**
     * 设置页数的初始值
     */
    public void setStartPage(int startPage) {
        this.startPage = startPage;
    }

    /**
     * 重置页数，刷新的时候会重置重置
     */
    public void resetPage() {
        page_no = startPage;
    }

    /**
     * 加载数量
     */
    public void setPageSize(int pageSize) {
        this.page_size = pageSize;
    }

    /**
     * 刷新使用的设置视图
     */
    @Override
    public void setNewData(@Nullable List<T> data) {
        super.setNewData(data);
        onViewIdleFirstWindow = true;
        page_no++;
        setRefresh(true);
        refreshCount++;
        isFirstRefresh = refreshCount == 1;
    }

    /**
     * 加载使用的，设置视图
     */
    @Override
    public void addData(@NonNull Collection<? extends T> newData) {
        super.addData(newData);
        page_no++;
        setRefresh(false);
    }


    /**
     * 设置没有更多的数据了。
     *
     * @param isShowNoData 是否显示无数据
     */
    @Override
    public void loadMoreEnd(boolean isShowNoData) {
        super.loadMoreEnd(isAdapterNoData ? !isShowNoData : true);
        if (refreshLayout != null && !isAdapterNoData) {
            //延迟设置setDisableLoadMore，避免正在关闭刷新控件，调用会马上结束问题，没有动画效果
            // 时间*2是因为refreshLayout 的tryScrollBackToTop调用2次
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (refreshLayout == null) return;
                    refreshLayout.setDisableLoadMore(true);
                    refreshLayout.setEnableNoMoreData(isShowNoData);
                    try {
                        notifyItemChanged(getLoadMoreViewPosition());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }, refreshLayout.getDurationToCloseHeader() * 2);
        }
    }

    public void loadMoreFail() {
        super.loadMoreFail();
        if (refreshLayout == null) return;
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (refreshLayout == null) return;
                refreshLayout.setDisableLoadMore(true);
            }
        }, refreshLayout.getDurationToCloseHeader() * 2);
    }

    public void loadMoreEnd() {
        loadMoreEnd(false);
    }

    /**
     * adapter的item是否显示无数据
     */
    public void loadMoreEnd2(boolean gone) {
        super.loadMoreEnd(gone);
    }

    /**
     * 解决闪烁问题
     */
    public void notifyItemRangeChanged() {
        if (getRecyclerView() != null) {
            ((SimpleItemAnimator) getRecyclerView().getItemAnimator()).setSupportsChangeAnimations(false);
        }
        try {
            notifyItemRangeChanged(0, getData().size());
        } catch (Exception e) {
            notifyDataSetChanged();
        }
    }


    public BaseNewViewHolder getViewHolder(int position) {
        if (getRecyclerView() != null) {
            return (BaseNewViewHolder) (getRecyclerView().findViewHolderForAdapterPosition(position + getHeaderLayoutCount()));
        }
        return null;
    }

    /**
     * 包含头部
     */
    public void notifyItemChangedAndHead(int position) {
        notifyItemChanged(position + getHeaderLayoutCount());
    }


    /**
     * 真正的第一个数据，也就是在多类型上面 ，排除EmptyHolder
     * 如果有增加其他的空界面，可在这边加入
     */
    public int getRealFirstPosition() {
        return realFirstPosition;
    }

    /**
     * 获取最后一项
     */
    public int getLastPosition() {
        try {
            return getData().size() - 1;
        } catch (Exception e) {
            return 0;
        }
    }

    /*********************************item 点击***********************************************/

    @Override
    protected void setOnItemClick(View v, int position) {
        if (mOnItemClickListener != null) {
            mOnItemClickListener.onItemClick(getViewHolder(position), getData().get(position % getData().size()));
        }
    }

    public interface OnItemClickListener<H extends BaseNewViewHolder, T> {
        void onItemClick(H holder, T bean);
    }

    private OnItemClickListener mOnItemClickListener;

    public final void setOnItemClickListener(@Nullable OnItemClickListener listener) {
        this.mOnItemClickListener = listener;
    }

    /*********************************item Long点击***********************************************/

    protected boolean setOnItemLongClick(View v, int position) {
        if (mOnItemLongClickListener != null) {
            return mOnItemLongClickListener.onItemLongClick(getViewHolder(position), getData().get(position % getData().size()));
        } else {
            return false;
        }
    }

    private OnItemLongClickListener mOnItemLongClickListener;

    public interface OnItemLongClickListener<H extends BaseNewViewHolder, T> {
        boolean onItemLongClick(H holder, T bean);
    }

    public final void setOnItemLongClickListener(@Nullable OnItemLongClickListener listener) {
        this.mOnItemLongClickListener = listener;
    }

    /*********************************item  里面的控件点击***********************************************/
    protected void setOnItemOtherClick(View v, int position) {
        if (mOnItemOtherClickListener != null) {
            mOnItemOtherClickListener.onItemOtherClick(getViewHolder(position), v, getData().get(position % getData().size()));
        }
    }

    public interface OnItemOtherClickListener<H extends BaseNewViewHolder, T> {
        void onItemOtherClick(H holder, View view, T bean);
    }

    public OnItemOtherClickListener mOnItemOtherClickListener;

    public final void setOnItemOtherClickListener(@Nullable OnItemOtherClickListener listener) {
        this.mOnItemOtherClickListener = listener;
    }

    /*********************************item  里面的控件long点击***********************************************/

    protected boolean setOnItemOtherLongClick(View v, int position) {
        if (mOnItemOtherLongClickListener != null) {
            return mOnItemOtherLongClickListener.onItemOtherLongClick(getViewHolder(position), v, getData().get(position % getData().size()));
        } else {
            return false;
        }
    }

    public interface OnItemOtherLongClickListener<H extends BaseNewViewHolder, T> {
        boolean onItemOtherLongClick(H holder, View view, T bean);
    }

    public OnItemOtherLongClickListener mOnItemOtherLongClickListener;

    public final void setOnItemOtherLongClickListener(@Nullable OnItemOtherLongClickListener listener) {
        this.mOnItemOtherLongClickListener = listener;
    }

    /**
     * 停止滚动的时候，第一个BaseViewHolder如果是当前的，则调用
     */
    public void onViewIdleFirstWindow(BaseNewViewHolder holder, boolean isAuto) {
        if (isAuto) {
            handler.removeMessages(MSG_FIRST_WINDOW);
            if (onViewIdleFirstWindow) {
                //延迟调用onViewIdleFirstWindow ，因为如果使用了scrollToPosition,会导致onViewIdleFirstWindow调用2次
                Message message = new Message();
                message.what = MSG_FIRST_WINDOW;
                message.obj = holder;
                handler.sendMessageDelayed(message, 100);
            }
        } else {
            onViewIdleFirstWindow(holder);
        }
        onViewIdleFirstWindow = false;
    }

    private void onViewIdleFirstWindow(BaseNewViewHolder holder) {
        onViewIdleFirstWindow = false;
        holder.onViewIdleFirstWindow();
        if (mRecyclerListener != null) {
            mRecyclerListener.onViewIdleFirstWindow(holder);
        }
    }


    /**
     * 进入监听
     */
    @Override
    public void onViewAttachedToWindow(BaseNewViewHolder holder) {
        super.onViewAttachedToWindow(holder);
        holder.onViewAttachedToWindow();
        if (mRecyclerListener != null) {
            mRecyclerListener.onViewAttachedToWindow(holder);
        }
    }

    /**
     * 离开监听
     */
    @Override
    public void onViewDetachedFromWindow(@NonNull BaseNewViewHolder holder) {
        super.onViewDetachedFromWindow(holder);
        holder.onViewDetachedFromWindow();
        if (mRecyclerListener != null) {
            mRecyclerListener.onViewDetachedFromWindow(holder);
        }
    }

    /**
     * 回收监听
     */
    @Override
    public void onViewRecycled(@NonNull BaseNewViewHolder holder) {
        super.onViewRecycled(holder);
        holder.onViewRecycled();
        if (mRecyclerListener != null) {
            mRecyclerListener.onViewRecycled(holder);
        }
    }

    public void setRefreshLayout(RefreshLayoutProxy refreshLayout) {
        this.refreshLayout = refreshLayout;
        //禁止refreshLayout加载
        if (refreshLayout != null) {
            refreshLayout.setDisableLoadMore(true);
//            refreshLayout.setEnableNoMoreData(true);
            refreshLayout.setEnableOverScroll(false);
            if (getRecyclerView() != null) {
                getRecyclerView().setNestedScrollingEnabled(false);
            }
        }
    }

    /**
     * 添加显示过的第一次动画
     */
    protected void setShowAmin(int position, boolean isAmin) {
        if (map_animate != null) {
            if (isAmin) {
                map_animate.put(position, true);
            } else {
                map_animate.put(position, false);
            }
        }
    }

    /**
     * 是否要显示 显示动画
     */
    protected boolean isShowAmin(int position) {
        if (map_animate == null) {
            return false;
        }
        if (map_animate.containsKey(position)) {
            return !map_animate.get(position);
        } else {
            return true;
        }
    }


    /**
     * 获取第一个可见的视图
     */
    public int getFirstVisibleItem() {
        int firstVisibleItem = -1;
        if (getRecyclerView() != null) {
            RecyclerView.LayoutManager layoutManager = getRecyclerView().getLayoutManager();
            if (layoutManager instanceof LinearLayoutManager) {
                firstVisibleItem = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();

            } else if (layoutManager instanceof StaggeredGridLayoutManager) {
                int[] positions = getOutRange();
                if (positions == null || positions.length != 2) {
                    return firstVisibleItem;
                }
                firstVisibleItem = positions[0];
            }

        }
        return firstVisibleItem;
    }

    /**
     * 获取最后一个可见的视图
     */
    public int getLastVisibleItem() {
        int lastVisibleItem = -1;
        if (getRecyclerView() != null) {
            RecyclerView.LayoutManager layoutManager = getRecyclerView().getLayoutManager();
            if (layoutManager instanceof LinearLayoutManager) {
                lastVisibleItem = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();

            } else if (layoutManager instanceof StaggeredGridLayoutManager) {
                int[] positions = getOutRange();
                if (positions == null || positions.length != 2) {
                    return lastVisibleItem;
                }
                lastVisibleItem = positions[1];
            }

        }
        return lastVisibleItem;
    }

    /**
     * 瀑布流可见范围
     */
    private int[] getOutRange() {
        RecyclerView.LayoutManager layoutManager = getRecyclerView().getLayoutManager();
        if (layoutManager instanceof StaggeredGridLayoutManager) {
            int[] range = new int[2];
            StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;
            int[] first = new int[staggeredGridLayoutManager.getSpanCount()];
            staggeredGridLayoutManager.findFirstVisibleItemPositions(first);

            int[] last = new int[staggeredGridLayoutManager.getSpanCount()];
            staggeredGridLayoutManager.findLastVisibleItemPositions(last);
            range[0] = first[0];

            Arrays.sort(last);
            range[1] = last[last.length - 1];
            return range;
        }
        return null;
    }

    /**
     * 是否使用adapter 的无数据
     * true 使用adapter无数据，false为刷新库的无数据
     */
    public void setAdapterNoData(boolean isAdapterNoData) {
        this.isAdapterNoData = isAdapterNoData;
    }

    @CallSuper
    public void destroy() {
        if (handler != null) {
            handler.removeCallbacksAndMessages(null);
        }
        for (int i = 0; i < getData().size(); i++) {
            if (getViewHolder(i) != null) {
                onViewRecycled(getViewHolder(i));
            }
        }
    }
}
